﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using SLS.ExClassLib.Events;
/*
 * 创建新纪录时，首先根据模板查询，然后将值传入新纪录
 */
namespace LanSunERP
{

    public partial class SQLFunction
    {
        public DataRow MapDataRow(string QueryType, string CONDTYPE, string TargetTable,
        DataRow dwSource, Queue ForeignKeyList, Queue PrimaryKeyList, bool Empty)
        {
            DataRow dwTarget = null;
            string TargetColumnName = "";
            string SourceColumnName = "";
            Queue RPrimaryKeyList = new Queue();
            Queue RForeignKeyList = new Queue();
            try
            {
                if (TargetTable.Contains("QueryCond"))
                {
                    dwTarget = setQueryCond.Tables[TargetTable].NewRow();
                }
                else
                {
                    dwTarget = setGlobal.Tables[TargetTable].NewRow();
                }

                if (dwTarget.Table.Columns.Contains("QUERYTYPE"))
                {
                    dwTarget["QUERYTYPE"] = QueryType;
                    dwTarget["CONDTYPE"] = CONDTYPE;
                }

                if (ForeignKeyList == null)
                {
                    foreach (DataColumn dcTemp in dwSource.Table.Columns)
                    {
                        string Column = dcTemp.ColumnName.ToString().Trim();
                        if (dwTarget.Table.Columns.Contains(Column))
                        {
                            if (dwTarget[Column].ToString().Trim() == "")
                            {
                                dwTarget[Column] = dwSource[Column];
                            }
                        }
                    }
                    return dwTarget;
                }

                while (ForeignKeyList.Count > 0)
                {
                    TargetColumnName = (string)PrimaryKeyList.Dequeue();
                    SourceColumnName = (string)ForeignKeyList.Dequeue();
                    if (dwTarget.Table.Columns.Contains(TargetColumnName)
                        && dwSource.Table.Columns.Contains(SourceColumnName))
                    {
                        if (dwTarget[TargetColumnName].ToString().Trim() == "")
                        {
                            dwTarget[TargetColumnName] = dwSource[SourceColumnName];
                        }
                    }
                    if (!Empty)
                    {
                        RPrimaryKeyList.Enqueue(TargetColumnName);
                        RForeignKeyList.Enqueue(SourceColumnName);
                    }
                }
                if (!Empty)
                {
                    PrimaryKeyList = RPrimaryKeyList;
                    ForeignKeyList = RForeignKeyList;

                }
            }
            catch (Exception ex)
            {
                Tracer.Error(ex.StackTrace, ex);
            }

            return dwTarget;
        }
        public DataRow MapDataRow(string QueryType, string CONDTYPE, DataRow dwTarget, DataRow dwSource,
            List<string> ForeignKeyList, List<string> PrimaryKeyList, bool Empty)
        {
            string TargetColumnName = "";
            string SourceColumnName = "";
            string TargetTable = dwTarget.Table.TableName;
            Queue RPrimaryKeyList = new Queue();
            Queue RForeignKeyList = new Queue();
            try
            {
                if (dwTarget == null)
                {
                    dwTarget = setGlobal.Tables[TargetTable].NewRow();
                }

                if (dwTarget.Table.Columns.Contains("QUERYTYPE"))
                {
                    dwTarget["QUERYTYPE"] = QueryType;
                    dwTarget["CONDTYPE"] = CONDTYPE;
                }

                if (ForeignKeyList == null)
                {
                    foreach (DataColumn dcTemp in dwSource.Table.Columns)
                    {
                        string Column = dcTemp.ColumnName.ToString().Trim();
                        if (dwTarget.Table.Columns.Contains(Column))
                        {
                            if (dwTarget[Column].ToString().Trim() == "")
                            {
                                dwTarget[Column] = dwSource[Column];
                            }
                        }
                    }
                    return dwTarget;
                }
                int count = ForeignKeyList.Count;
                for (int i = 0; i < count; i++)
                {
                    TargetColumnName = (string)PrimaryKeyList[i];
                    SourceColumnName = (string)ForeignKeyList[i];
                    if (dwTarget.Table.Columns.Contains(TargetColumnName)
                        && dwSource.Table.Columns.Contains(SourceColumnName))
                    {
                        if (dwTarget[TargetColumnName].ToString().Trim() == "")
                        {
                            dwTarget[TargetColumnName] = dwSource[SourceColumnName];
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Tracer.Error(ex.StackTrace, ex);
            }

            return dwTarget;
        } 
        public DataRow UpdateLastPOS(DataRow dwTarget, DataRow dwReference)
        {
            DataRow dwQueryCond;
            string TBName;
            string TBQueryCond;
            string QueryCond = "";
            int LastPoisitionID = 0;
            int PoisitionID = 0;
            try
            {

                if (dwReference != null)
                {
                    TBName = dwReference.Table.TableName;
                    TBQueryCond = TBName + "QueryCond";
                    #region Update the Model's LastPoisitionID
                    LastPoisitionID = System.Convert.ToInt16(dwReference["LASTPOS"].ToString()) + 1;
                    dwReference["LASTPOS"] = LastPoisitionID;
                    dwReference.AcceptChanges();
                    dwQueryCond = setQueryCond.Tables[TBQueryCond].NewRow();
                    dwQueryCond = MapDataRow("QueryOnly", "DB_" + TBName + "_UPDATE_BY_UID", TBQueryCond, dwReference, null, null, true);
                    dsResult = new DataSet();
                    dsResult = QueryAndCreateTable(dwQueryCond);
                    #endregion

                    #region Update the the new records' PoisitionID
                    dwTarget["LASTPOS"] = 1;
                    if (TBName == "G")
                    {
                        PoisitionID = LastPoisitionID;
                        dwTarget[""] = dwReference[""];
                    }
                    else
                    {
                        PoisitionID = System.Convert.ToInt16(dwReference["POS"].ToString());
                        dwTarget[""] = dwReference[""].ToString().Trim() + "." + LastPoisitionID.ToString();
                    }
                    #endregion

                    dwTarget = Build(dwTarget, PoisitionID);
                //    Tracer.Verbose("UpdateLastPOS", dwTarget);
                }
            }
            catch (Exception ex)
            {
                Tracer.Error(ex.StackTrace, ex);
            }
            return dwTarget;
        }
        public virtual DataRow Build(DataRow dwSource, int POS, int Line = 0)
        {
            string SubStatus = dwSource["SUBSTATUS"].ToString().Trim();
            string Status = dwSource["STATUS"].ToString().Trim();
            
            try
            {
                dwSource["UID"] = Guid.NewGuid().ToString().ToUpper();
                dwSource["POS"] = POS;
                dwSource["SUBSTATUS"] = SubStatus + "New";
                dwSource["STATUS"] = Status + "New";
                //Tracer.Verbose("UpdateLastPOS", dwSource);
            }
            catch (Exception ex)
            {
                Tracer.Error(ex.StackTrace, ex);
            }
            return dwSource;
        }
        public SqlCommand Build(SqlCommand cmdSQL, DataRow dwRequest)
        {
            string TBName = dwRequest.Table.TableName;
            Queue PKQueue = GetPrimaryKey(TBName);
            string PKey = "";
            while (PKQueue.Count > 0)
            {
                PKey = (string)PKQueue.Dequeue();
            } 
            return cmdSQL;

        }
        private void InsertRecord(DataRow dwSource, string TBName)
        {
            try
            {
                dwSource["QUERYTYPE"] = "QueryOnly";
                dwSource["CONDTYPE"] = "DB_" + TBName + "_INSERT";
                QueryAndCreateTable(dwSource);
                //Tracer.Verbose("InsertRecord", dwSource);
            }
            catch (Exception ex)
            {
                Tracer.Error(ex.StackTrace, ex);
            }
        }
        private void UpdateRecord(DataRow dwSource, string TBName)
        {
            try
            {
                dwSource["QUERYTYPE"] = "QueryOnly";
                dwSource["CONDTYPE"] = "DB_" + TBName + "_UPDATE_BY_UID";
                QueryAndCreateTable(dwSource);
                //Tracer.Verbose("UpdateRecord", dwSource);
            }
            catch (Exception ex)
            {
                Tracer.Error(ex.StackTrace, ex);
            }
        }
        private DataRow IsExistRecord(DataRow dwQueryCond, string TBName)
        {
            DataRow rowReturn = null;

            try
            {
                dwQueryCond["QUERYTYPE"] = "QueryOnly";
                dwQueryCond["CONDTYPE"] = "DB_" + TBName + "_SELECT_BY_UID";
                dsResult = new DataSet();
                dsResult = QueryAndCreateTable(dwQueryCond);
                if (dsResult.Tables.Contains(TBName))
                {
                    if (dsResult.Tables[TBName].Rows.Count > 0)
                    {
                        Tracer.Info(logRoute + ".IsExistRecord",dwQueryCond.ToString());
                        rowReturn = dsResult.Tables[TBName].Rows[0];
                    }
                    else
                    {
                        dwQueryCond["QUERYTYPE"] = "QueryOnly";
                        dwQueryCond["CONDTYPE"] = "PK_" + TBName;
                        dsResult = new DataSet();
                        dsResult = QueryAndCreateTable(dwQueryCond);
                        if (dsResult.Tables.Contains(TBName))
                        {
                            if (dsResult.Tables[TBName].Rows.Count > 0)
                            {
                                rowReturn = dsResult.Tables[TBName].Rows[0];
                            }
                        }
                    }
                }
                if (rowReturn == null)
                {
                    rowReturn = dwQueryCond;
                }
            }
            catch (Exception ex)
            {
                Tracer.Error(ex.StackTrace, ex);
            }
            //Tracer.Verbose("IsExistRecord.Source", dwQueryCond);
            //Tracer.Verbose("IsExistRecord.Result", rowReturn);
            return rowReturn;
        }
        public DataTable ImportDataRow(DataRow DataRowSrc)
        {
            DataTable objectTable = DataRowSrc.Table.Clone();//必须先复制表的架构，使具有相同的的列或关系！ 
            objectTable.Rows.Add(DataRowSrc.ItemArray);//在objectTable中添加一个新行，并将sourceRow的值复制进去,要求表的结构一样！
            return objectTable;
        }
        public DataSet ImportDataTable(DataSet setOutPut, DataTable tableSource)
        {
            if (setOutPut == null)
            {
                setOutPut = new DataSet();
            }
            try
            {
                setOutPut.Merge(tableSource, true, MissingSchemaAction.Add);
            }
            catch (Exception ex)
            {
                Tracer.Error(ex.StackTrace, ex);
            }
            return setOutPut;
        }
        public DataSet ImportDataTable(DataSet setOutPut, DataRow dwSourceRecord)
        {
            DataTable dtObject;
            if (setOutPut == null)
            {
                setOutPut = new DataSet();
            }
            dtObject = this.ImportDataRow(dwSourceRecord);
            setOutPut.Merge(dtObject, true, MissingSchemaAction.Add);
            return setOutPut;
        }
        private List<string> GetSourceForeingKey(string TBName, string ForeignKey, DataRow dwForeignKey = null)
        {
            List<string> ListForeignKey = new List<string>();
            string XKey;
            string expression;
            if (dwForeignKey == null)
            {
                expression = "TBNAME='" + TBName + "' and FOREIGNKEY='" + ForeignKey + "'";
                dwForeignKeyLists = TBForeignKeyList.Select(expression);
                dwForeignKeyList = null;
                if (dwForeignKeyLists.Count() > 0)
                {
                    dwForeignKey = dwForeignKeyLists[0];
                }
            }
            for (int i = 0; i <= 9; i++)
            {
                XKey = dwForeignKey["KEY" + i.ToString()].ToString().Trim();
                if (XKey != "")
                {
                    ListForeignKey.Add(XKey);
                }
            }
            //Tracer.Verbose("GetSourceForeingKey:", dwForeignKey);
            return ListForeignKey;
        }
        private List<string> GetTargetForeingKey(string TBName, string ForeignKey, DataRow dwForeignKey = null)
        {
            List<string> ListForeignKey = new List<string>();
            string XKey;
            string expression = "";
            if (dwForeignKey == null)
            {
                expression = "TBNAME='" + TBName + "' and FOREIGNKEY='" + ForeignKey + "'";
                dwForeignKeyLists = TBForeignKeyList.Select(expression);
                dwForeignKeyList = null;
                if (dwForeignKeyLists.Count() > 0)
                {
                    dwForeignKey = dwForeignKeyLists[0];
                }
            }
            for (int i = 0; i <= 9; i++)
            {
                XKey = dwForeignKey["TKEY" + i.ToString()].ToString().Trim();
                if (XKey != "")
                {
                    ListForeignKey.Add(XKey);
                }
            }
            //Tracer.Verbose("GetTargetForeingKey:", dwForeignKey);
            return ListForeignKey;
        }
        private List<string> GetAbsoluteGDKEY(string TBName, string ForeignKey, DataRow dwForeignKey = null)
        {
            List<string> ListForeignKey = new List<string>();
            string XKey;
            string expression = "";

            if (dwForeignKey == null)
            {
                expression = "TBNAME='" + TBName + "' and FOREIGNKEY='PK_" + TBName + "' and TYPE='PrimaryKey'";
                dwForeignKeyLists = TBForeignKeyList.Select(expression);
                dwForeignKeyList = null;
                if (dwForeignKeyLists.Count() > 0)
                {
                    dwForeignKey = dwForeignKeyLists[0];
                }
            }
            for (int i = 0; i <= 9; i++)
            {
                XKey = dwForeignKey["KEY" + i.ToString()].ToString().Trim();
                if (XKey != "SM"
                    && XKey != "KEYDEFTYPE"
                    && XKey != "GTPRE"
                    && XKey != "GTKEY"
                    && XKey != ""
                    )
                {
                    ListForeignKey.Add(XKey);
                }
            }
            //Tracer.Verbose("GetAbsoluteGDKEY:", dwForeignKey);
            return ListForeignKey;
        }
        public void DeleteRecord(DataSet setRequest)
        {
            string TBName;
            DataRow dwQueryCond;
            //Tracer.Verbose("DeleteRecord:", setRequest);
            try
            {
                foreach (DataTable tbTemp in setRequest.Tables)
                {
                    TBName = tbTemp.TableName;
                    dwQueryCond = setQueryCond.Tables[TBName + "QueryCond"].NewRow();
                    dwQueryCond["QUERYTYPE"] = "QueryOnly";
                    dwQueryCond["CONDTYPE"] = "DB_" + TBName + "_DELETE_BY_UID";
                    foreach (DataRow dwTemp in tbTemp.Rows)
                    {
                        dwQueryCond["UID"] = dwTemp["UID"]; 
                        QueryAndCreateTable(dwQueryCond);
                    }
                }
            }
            catch (Exception ex)
            {
                Tracer.Error(ex.StackTrace, ex);
            }
        } 
    }
}